<?php 
/* provides methods from the web analytics */
class analytics {	
	private $cache;
	
	/* constructs this class and 
	 * instanciates the cache */
	public function __construct(){
		// instanciate the cache
		$this->cache = new cache();
	}
	
	/* returns the users unique id which 
	 * in case of Google Analytics is stored 
	 * in the "__umta" cookie */
	public function getUqId(){
		$result = "";
		
		// check if the uqid cookie exists
		if(array_key_exists("__utma", $_COOKIE)){
			// set the uqid value
			$result = str_replace(".","D",$_COOKIE["__utma"]);
		}
		
		return $result;
	}
	
	// determines for which month reports are already
	// available on a monthly basis as reports that are
	// run on the first of a month might not have values
	public function getReportingMonth(){
		$result = array("number" => date("m"), 
						"name" => strftime("%B"));
		if(date("d")=="01"){
			$ts = strtotime("-1 month");
			$result = array("number" => date("m",$ts), 
						"name" => strftime("%B",$ts));
		}
		
		return $result;
	}
	
	// does the same as 'get_ga_also_interested_in',
	// but caches the data for 24hrs on the disk which
	// provides way, way better performance
	public function getCachedThisMonthsTopArticles($month, $refresh = false){
		// result will hold the recommendations
		$result = array();

		// generate the cache key for the recommendations
		$cache_key = $this->cache->hash(CONFIG_GA_SITE_PROFILE_ID."toppages");
		
		// check whether the recommendations exist in cache
		if($this->cache->has($cache_key)==true && $refresh==false){
			$result = $this->cache->get($cache_key);
		}else{
			// query the recommendations from google
			$result = $this->getThisMonthsTopArticles($month);
			
			// put the recommendations into the cache for 1 day
			$this->cache->put($cache_key, $result, time()+86400);
		}

		// finally return the recommendations
		return $result;
	}
	
	// this method queries the top articles from
	// google analytics to then return them as
	// and array
	public function getThisMonthsTopArticles($month){
		$result = array();
		
		// get the list of articles from the database
		$_b = new blog($_SERVER["HTTP_HOST"]);
		$db = $_b->db;
		
		$list = $db->getArticleList();
		
		// traffic data from the first to the last of this month
		$startdate = strtotime($month.'/01/'.date('Y').' 00:00:00');
		$endate = strtotime('-1 second',strtotime('+1 month',strtotime
							($month.'/01/'.date('Y').' 00:00:00')));
	
		// create the query for the top pages report
		$r_url = "https://www.google.com/analytics/feeds/data"
				."?v=2&ids=ga:".CONFIG_GA_SITE_PROFILE_ID."&metrics=ga:pageviews"
				."&sort=-ga:pageviews&max-results=30&dimensions=ga:pagePath"
				."&start-date=".date("Y-m-d",$startdate)
				."&end-date=".date("Y-m-d",$endate);
				
		// pretty print makes the result readable xml
		//$r_url .= "&prettyprint=true";
				
		$result_xml = $this->getGoogleAnalyticsFeed($r_url);
		// we need to replace the 'dxp:' namespace as otherwise
		// it is getting very complicated with simplexml to retrieve
		// the values for it - a simple replacement makes it lot easier
		$xml = simplexml_load_string(str_replace
					("dxp:","dxp",$result_xml));
		
		// build the result array
		$a = 0;
		for($e=0;$e<count($xml->entry);$e++){
			$entry = $xml->entry[$e];
			$p_url = (string)$entry->dxpdimension->attributes()->value;
			$t_url = substr($p_url,1,strlen($p_url)-6);
			
			// make sure the url is an article
			if(substr($p_url, strlen($p_url)-4)=="html"){				
				// get the database information about the article
				for($l=0;$l<count($list);$l++){
					if($list[$l]["url"]==$t_url){
						// add the suggestion with its analytics data
						// only when the article exists in the database
						$result[$a] = array();
						$result[$a]['url'] = $t_url;
						$result[$a]['views'] = (int)$entry->dxpmetric->attributes()->value;
						$result[$a]["title"] = $list[$l]["title"];
					}
				}
				
				$a++;
			}
		}
		return $result;		
	}
	
	// does the same as 'get_ga_also_interested_in',
	// but caches the data for 24hrs on the disk which
	// provides way, way better performance
	public function getCachedRecommendations($page,$refresh = false){
		// result will hold the recommendations
		$result = array();

		// generate the cache key for the recommendations
		$cache_key = $this->cache->hash(CONFIG_GA_SITE_PROFILE_ID."recommendations".$page);
		
		// check whether the recommendations exist in cache
		if($this->cache->has($cache_key)==true && $refresh==false){
			$result = $this->cache->get($cache_key);
		}else{
			// query the recommendations from google
			$result = $this->getRecommendations($page);
			
			// put the recommendations into the cache for 1 day
			$this->cache->put($cache_key, $result, time()+86400);
		}
		
		// finally return the recommendations
		return $result;
	}
	
	/*
	Returns the pages that other users also viewed
	that viewed the page provided as parameter. The
	param needs to have the full url of the page
	e.g.: '/wlan-sendeleistung-erhoehen.html'
	
	result as array in the following format:
		arr['url'] = '/article.html'
		arr['views'] = 34
		arr['percent'] = 73
		
	^ percent would be the number of users that
		actually viewed the suggested page
	*/
	public function getRecommendations($page){
		$suggestions = array();
		
		// get the list of articles from the database
		$_b = new blog($_SERVER["HTTP_HOST"]);
		$db = $_b->db;
		
		$list = $db->getArticleList();
		
		// traffic data from the last 5 days will be used
		$startdate = time()-(86400*90); // minus 90 days (3 months)
		$endate = time()-86400; // yesterday
	
		$r_url = "https://www.google.com/analytics/feeds/data"
				."?v=2&ids=ga:".CONFIG_GA_SITE_PROFILE_ID."&metrics=ga:pageviews"
				."&sort=-ga:pageviews&max-results=30&dimensions=ga:pagePath"
				."&start-date=".date("Y-m-d",$startdate)
				."&end-date=".date("Y-m-d",$endate)
				."&segment=dynamic::ga:pagePath%3D%3D".urlencode($page);
		
		$result_xml = $this->getGoogleAnalyticsFeed($r_url);
		// we need to replace the 'dxp:' namespace as otherwise
		// it is getting very complicated with simplexml to retrieve
		// the values for it - a simple replacement makes it lot easier
		$xml = simplexml_load_string(str_replace
					("dxp:","dxp",$result_xml));

		// get the total pvs to calculate the percentage
		if($xml!==false){
			$totalPvs = $xml->dxpaggregates->dxpmetric->attributes()->value;
			
			// build the result array
			$a = 0;
			for($e=0;$e<count($xml->entry);$e++){
				$entry = $xml->entry[$e];
				$p_url = (string)$entry->dxpdimension->attributes()->value;
				$t_url = substr($p_url,1,strlen($p_url)-6);
				// make sure the url is an article
				if(substr($p_url, strlen($p_url)-4)=="html"){				
					// get the database information about the article
					for($l=0;$l<count($list);$l++){
						if($list[$l]["url"]==$t_url){
							// add the suggestion with its analytics data
							// only when the article exists in the database
							$suggestions[$a] = array();
							$suggestions[$a]['url'] = $t_url;
							$entry_pvs = (int)$entry->dxpmetric->attributes()->value;
							$entry_percent = round(($entry_pvs/$totalPvs)*100,0);
							$suggestions[$a]['views'] = $entry_pvs;
							$suggestions[$a]['percent'] = $entry_percent;
							$suggestions[$a]["title"] = $list[$l]["title"];
						}
					}
					
					$a++;
				}
			}
		}
		return $suggestions;
	}
	
	// requests an analytics feed with client-login auth
	private function getGoogleAnalyticsFeed($feedUri){
		$token = $this->getGoogleAnalyticsToken();
		
		$curl = curl_init($feedUri);
		// add the auth header
		curl_setopt($curl, CURLOPT_HTTPHEADER, array
			("Authorization: GoogleLogin auth=".$token));
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
		$ga_resp = curl_exec($curl);
		curl_close($curl);
		return $ga_resp;
	}
	
	// curls the token and returns it
	private function getGoogleAnalyticsToken(){
		$authToken = "";
		$user = CONFIG_GA_USERNAME;	
		$pass = base64_decode(CONFIG_GA_PASSWORD);
		
		$curl = curl_init("https://www.google.com/accounts/ClientLogin");
		curl_setopt($curl, CURLOPT_POST, 1);
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($curl, CURLOPT_POSTFIELDS, 
				"Email=".$user."&Passwd=".$pass."&accountType=GOOGLE"
				."&service=analytics&source=kammerath.net-server");
		$ga_resp = curl_exec($curl);
		curl_close($curl);
		 
		$lines = explode("\n",$ga_resp);  
	  
		foreach ($lines as $line) {  
			$keyValue = explode("=", $line);  
	  		if($keyValue[0]=="Auth"){  
				$authToken = $keyValue[1];   
			}
		}  
	  
		return $authToken; 
	}	
}
?>